/**
 * WebSocket客户端工具类
 */
class WebSocketClient {
  constructor() {
    this.socket = null
    this.isConnected = false
    this.reconnectTimer = null
    this.reconnectAttempts = 0
    this.maxReconnectAttempts = 5
    this.reconnectInterval = 3000
    this.heartbeatTimer = null
    this.heartbeatInterval = 30000
    this.messageHandlers = []
    this.url = ''
  }

  /**
   * 连接WebSocket
   */
  connect() {
    try {
      // 获取token - 使用正确的key
      const token = uni.getStorageSync('edu_token')
      if (!token) {
        console.error('WebSocket连接失败: 未找到token')
        console.log('请先登录')
        // 不显示toast，由调用方处理
        return
      }

      // 构建WebSocket URL - 根据环境动态配置
      // #ifdef H5
      if (typeof window !== 'undefined') {
        const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'
        const hostname = window.location.hostname
        const host = (hostname === 'localhost' || hostname === '127.0.0.1') ? 'localhost:8866' : `${hostname}:8866`
        this.url = `${protocol}//${host}/ws/chat?token=${token}`
      } else {
        this.url = `ws://localhost:8866/ws/chat?token=${token}`
      }
      // #endif
      
      // #ifndef H5
      // 小程序等其他环境使用固定地址
      this.url = `ws://localhost:8866/ws/chat?token=${token}`
      // #endif
      
      console.log('WebSocket连接中...', this.url)
      console.log('Token存在:', !!token)
      
      this.socket = uni.connectSocket({
        url: this.url,
        success: () => {
          console.log('WebSocket连接请求发送成功')
        },
        fail: (error) => {
          console.error('WebSocket连接请求失败:', error)
        }
      })

      // 监听连接打开
      this.socket.onOpen(() => {
        console.log('WebSocket连接已建立')
        this.isConnected = true
        this.reconnectAttempts = 0
        this.startHeartbeat()
      })

      // 监听消息
      this.socket.onMessage((res) => {
        try {
          const data = JSON.parse(res.data)
          console.log('WebSocket收到消息:', data)
          
          // 处理心跳响应
          if (data.type === 'HEARTBEAT') {
            return
          }
          
          // 通知所有消息处理器
          this.messageHandlers.forEach(handler => {
            try {
              handler(data)
            } catch (error) {
              console.error('消息处理器执行失败:', error)
            }
          })
        } catch (error) {
          console.error('解析WebSocket消息失败:', error)
        }
      })

      // 监听连接关闭
      this.socket.onClose((res) => {
        console.log('WebSocket连接已关闭:', res)
        this.isConnected = false
        this.stopHeartbeat()
        
        // 显示连接关闭提示
        if (res.code !== 1000) {
          uni.showToast({
            title: '消息服务已断开',
            icon: 'none',
            duration: 2000
          })
          this.reconnect()
        }
      })

      // 监听连接错误
      this.socket.onError((error) => {
        console.error('WebSocket连接错误:', error)
        this.isConnected = false
        this.stopHeartbeat()
        
        uni.showToast({
          title: 'WebSocket连接失败，请检查网络',
          icon: 'none',
          duration: 2000
        })
        
        this.reconnect()
      })

    } catch (error) {
      console.error('WebSocket连接异常:', error)
    }
  }

  /**
   * 断开连接
   */
  disconnect() {
    if (this.socket) {
      this.isConnected = false
      this.stopHeartbeat()
      this.stopReconnect()
      
      this.socket.close({
        code: 1000,
        reason: '主动断开'
      })
      
      this.socket = null
      console.log('WebSocket已主动断开')
    }
  }

  /**
   * 发送消息
   */
  send(data) {
    if (!this.isConnected || !this.socket) {
      console.warn('WebSocket未连接，消息发送失败')
      return false
    }

    try {
      const message = typeof data === 'string' ? data : JSON.stringify(data)
      this.socket.send({
        data: message,
        success: () => {
          console.log('WebSocket消息发送成功:', data)
        },
        fail: (error) => {
          console.error('WebSocket消息发送失败:', error)
        }
      })
      return true
    } catch (error) {
      console.error('WebSocket发送消息异常:', error)
      return false
    }
  }

  /**
   * 添加消息处理器
   */
  onMessage(handler) {
    if (typeof handler === 'function') {
      this.messageHandlers.push(handler)
    }
  }

  /**
   * 移除消息处理器
   */
  offMessage(handler) {
    const index = this.messageHandlers.indexOf(handler)
    if (index > -1) {
      this.messageHandlers.splice(index, 1)
    }
  }

  /**
   * 重连
   */
  reconnect() {
    if (this.reconnectAttempts >= this.maxReconnectAttempts) {
      console.log('WebSocket重连次数已达上限，停止重连')
      return
    }

    this.reconnectAttempts++
    console.log(`WebSocket第${this.reconnectAttempts}次重连...`)

    this.reconnectTimer = setTimeout(() => {
      this.connect()
    }, this.reconnectInterval)
  }

  /**
   * 停止重连
   */
  stopReconnect() {
    if (this.reconnectTimer) {
      clearTimeout(this.reconnectTimer)
      this.reconnectTimer = null
    }
  }

  /**
   * 开始心跳
   */
  startHeartbeat() {
    this.stopHeartbeat()
    
    this.heartbeatTimer = setInterval(() => {
      if (this.isConnected) {
        this.send({
          type: 'HEARTBEAT',
          message: 'ping'
        })
      }
    }, this.heartbeatInterval)
  }

  /**
   * 停止心跳
   */
  stopHeartbeat() {
    if (this.heartbeatTimer) {
      clearInterval(this.heartbeatTimer)
      this.heartbeatTimer = null
    }
  }

  /**
   * 获取连接状态
   */
  getConnectionState() {
    return {
      isConnected: this.isConnected,
      reconnectAttempts: this.reconnectAttempts,
      url: this.url
    }
  }
  
  /**
   * 检查是否已连接
   */
  get connected() {
    return this.isConnected
  }
}

export default WebSocketClient
